package com.bytedance.speech.speechdemo

import android.content.Context
import android.util.Log
import com.bytedance.speech.speechdemo.audio.AudioRecordFunc
import java.io.File
import java.io.FileOutputStream
import java.nio.ByteBuffer
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

//import org.webrtc.audio.WebRtcAudioRecord;
/**
 * 录音和识别服务 （包含webrtc音频数据流识别处理）
 */
object AudioRecognitionService {

    //必须调用完后flip()才可以调用此方法
    fun conver(byteBuffer: ByteBuffer): ByteArray? {
        byteBuffer.flip()
        val len = byteBuffer.limit() - byteBuffer.position()
        val bytes = ByteArray(len)
        if (byteBuffer.isReadOnly) {
            return null
        } else {
            byteBuffer[bytes]
        }
        byteBuffer.compact()
        return bytes

    }

    private var execServiceStartTime: Long=0
    private var isRecord: Boolean=false;
    private var outFile: File?=null;
    private var outFileStream:FileOutputStream?=null;
    private var now: Long=0L
    private var startWriteAudioTime: Long=0L;
    var TAG = "AudioRecon"
    /**缓存区50KB 超过缓冲区的数据则丢弃*/
//    var byteBuffer1 = ByteBuffer.allocateDirect(1024 * 1024 )
//    var byteBuffer2 = ByteBuffer.allocateDirect( 1024 * 1024 )
    var execService: ExecutorService? = null
    @Volatile
    var isAudioTrigger = false
    @Volatile
    var isFinishRead = true
    var faild:Int=0;
    val STATUS_INITIALIZE = -3
    val STATUS_BUFFER_FRIST = -2
    val STATUS_BUFFER_SECOND = -1
    val STATUS_BUFFER_ACTION_FRIST = 0
    val STATUS_BUFFER_ACTION_SECOND = 1
    val STATUS_BUFFER_ACTION_THRID = 2
    private var counterIndex = STATUS_INITIALIZE.toLong()
    private var counterTime: Long = 0
//    lateinit var iflytekManger: IflytekManger

    var byteBuffer1 = ByteBuffer.allocateDirect(1024 * 1024  *2)
    var byteBuffer2 = ByteBuffer.allocateDirect( 1024 * 1024 *2)

    interface ReadByteToListen{
        fun read(audioData: ByteArray, size: Int)
    }
    var readByteToListen:ReadByteToListen?=null


    //    var myListen=MyRecognizerListener()
    private var ret = 0
    fun start(context: Context,readByteToListen:ReadByteToListen) {
        this.readByteToListen = readByteToListen
        if(execService==null)
        {
            execService = Executors.newFixedThreadPool(5)
        }
        playAudioRecordFunc()
    }

    fun putData(buffer: ByteBuffer, data: ByteArray) {
        val cacheSize = buffer.capacity() - buffer.position()
        if (cacheSize >= data.size) {
            buffer.put(data)
        }
    }

    var aidioDataListen = AudioRecordFunc.AudioDataBytesSamplesListen { data ->
        try {

            if (isRecord) {
                outFileStream?.write(data)
            }

            now = System.currentTimeMillis();
            if (counterIndex == STATUS_INITIALIZE.toLong()) {
                counterTime = now
                counterIndex = STATUS_BUFFER_FRIST.toLong()
            }
            if (isAudioTrigger) {
                Log.e(TAG, "data put->" + data.size)
                conver(byteBuffer1)
                conver(byteBuffer2)
                isAudioTrigger = false
            }
            try {
                putData(byteBuffer1, data)
                putData(byteBuffer2, data)
            } catch (e: Exception) {
            }
            val tempCounterIndex = (now - counterTime) / 2000L
            Log.d("TAG", "tempCounterIndex->")
            if (counterIndex != tempCounterIndex) {
                counterIndex = tempCounterIndex
                val index = (counterIndex % 2).toInt()
                when (index) {
                    0 -> read(byteBuffer1)
                    1 -> read(byteBuffer2)
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
//
    fun read(byteBuffer: ByteBuffer) {
        val audioData = conver(byteBuffer)
        execServiceStartTime=System.currentTimeMillis();
        execService!!.submit {

            Log.d(TAG,"!isAudioTrigger="+(!isAudioTrigger)+" "+audioData!!.size)
            if (audioData != null && !isAudioTrigger) {

                readByteToListen?.read(audioData,audioData.size)
//                read(audioData!!, myListen)
            }else{
                isAudioTrigger=false
            }

            Log.d("IflytekManger","队列耗时:"+(System.currentTimeMillis()-execServiceStartTime))
        }
    }
//
//    public fun read(audioData:ByteArray,listen: RecognizerListener){
////        setParam()
//        startWriteAudioTime=System.currentTimeMillis()
//        Log.d(TAG," startWriteAudioTim")
//        ret = mIat!!.startListening(listen)
//        if (ret != ErrorCode.SUCCESS) {
//            Log.d(TAG,"识别失败,错误码：$ret,请点击网址https://www.xfyun.cn/document/error-code查询解决方案")
//        } else {
//            mIat!!.writeAudio(audioData, 0, audioData.size)
//            mIat!!.stopListening()
//        }
//    }


    fun playAudioRecordFunc() {
        Log.e(TAG, "playAudioRecordFunc()")
        AudioRecordFunc.getInstance().setAudioDataBytesSamplesListen(aidioDataListen)
        AudioRecordFunc.getInstance().isWriteFile = false
        AudioRecordFunc.getInstance().startRecordAndFile()
    }

    fun stop() {
        byteBuffer1.clear()
        byteBuffer2.clear()
        AudioRecordFunc.getInstance().stopRecordAndFile()
    }



}